package tagging;

import java.util.Vector;
import java.io.*;

public class Parser {
  public static class ParserException extends Exception {
    public ParserException(final String error) {
      super(error);
    }
  }
  
  public static class ProcessedWord {
    String original_word_;
    String word_;
    String tag_;
    boolean isUnknown_;
    
    public ProcessedWord(String word, String tag) {
      original_word_ = word;
      word_ = word.toLowerCase();
      tag_ = tag;
      isUnknown_ = false;
    }
    
    public ProcessedWord(String word) {
      original_word_ = word;
      word_ = word.toLowerCase();
      isUnknown_ = false;
      tag_ = null;
    }
    
    public void setTag(String tag) {
      tag_ = tag;
    }
    
    public void setUnknownBit() {
      isUnknown_ = true;
    }
    
    public String getOriginalWord() {
      return original_word_;
    }
    
    public String getWord() {
      return word_;
    }
    
    public String getTag() {
      return tag_;
    }
    
    public boolean isUnknown() {
      return isUnknown_;
    }
  }
  
  String fileName_;
  FileReader fr_;
  BufferedReader in_;
  boolean isTraining_;
  boolean done_;
  boolean start_;

  public Parser(String fileName, boolean isTraining) throws ParserException {
    fileName_ = fileName;
    
    fr_ = null;
    try {
      fr_ = new FileReader(new File(fileName));
    } catch (FileNotFoundException e) {
      throw new ParserException(e.getMessage());
    }

    in_ = new BufferedReader(fr_);
    start_ = true;
    isTraining_ = isTraining;
  }

  public boolean parseNextSentence(Vector<ProcessedWord> pwords) throws ParserException {
    String str;    
        
    try {
      if (start_) {
        start_ = false;
        done_ = false;
        // Read and ignore the first start-sentence marker.
        str = in_.readLine();
      } else if (done_) {
        in_.close();
        fr_.close();
        
        return false;
      }
    } catch (IOException e) {
      throw new ParserException(e.getMessage());
    }

    pwords.clear();
    ProcessedWord pw = null;
    if (isTraining_) {
      pw = new ProcessedWord(Tag.START_TAG, Tag.START_TAG);
      pwords.add(pw);
    } else {
      pw = new ProcessedWord(Tag.START_TAG);
      pwords.add(pw);
    }
    
    while (true) {
      try {
        str = in_.readLine();
      } catch (IOException e) {
        throw new ParserException(e.getMessage());
      }

      if (str == null) {
        done_ = true;
        break;
      }
      
      if (str.startsWith(Tag.START_TAG)) {
        break;
      }
      
      if (isTraining_) {
        String[] tokens = str.split(" ");
        String currentTag = tokens[0];
        String currentWord = str.substring(currentTag.length() + 1);
        
        pw = new ProcessedWord(currentWord, currentTag);
        pwords.add(pw);
      } else {
        pw = new ProcessedWord(str);
        pwords.add(pw);
      }
    }
    
    return true;
  }
  
  public String getFileName() {
    return fileName_;
  }
}
